package cz.mff.cuni.dpp.liboptions;

import java.util.Set;

/**
 * Podtřída {@link Option Option} pro volby s celočíselným parametrem.
 */
public class IntegerOption extends Option<Integer> {

	/**
	 * inclusive
	 */
	private final int lowerBound;
	private final int upperBound;

	public IntegerOption(String primaryName, Set<String> aliases, boolean obligatory,
			String valuePlaceholder, String description, OptionCallback<Integer> callback) {
		super(primaryName, aliases, obligatory, valuePlaceholder, description, callback);
		lowerBound = Integer.MIN_VALUE;
		upperBound = Integer.MAX_VALUE;
	}

	public IntegerOption(String primaryName, Set<String> aliases, boolean obligatory,
			String valuePlaceholder, String description, OptionCallback<Integer> callback,
			int lowerBound, int upperBound) {
		super(primaryName, aliases, obligatory, valuePlaceholder, description, callback);
		this.lowerBound = lowerBound;
		this.upperBound = upperBound;
	}

	protected IntegerOption(Builder builder) {
		super(builder);
		this.lowerBound = builder.getLowerBound();
		this.upperBound = builder.getUpperBound();
	}

	public boolean supportsValue() {
		return true;
	}

	public Integer parseValue(String value) throws BadValueException {
		Integer intValue = null;

		try {
			intValue = Integer.parseInt(value);
		} catch (NumberFormatException e) {
			throw new BadValueException(value, this);
		}

		if (intValue < lowerBound || intValue > upperBound) {
			throw new BadValueException(value, this, true);
		}

		return intValue;
	}

	public int getLowerBound() {
		return lowerBound;
	}

	public int getUpperBound() {
		return upperBound;
	}

    /**
     * Builder pro objekty typu {@link IntegerOption}, potomek {@link
     * Option.Builder}
     */
	public static class Builder extends Option.Builder<Integer, Builder> {

		private int lowerBound = Integer.MIN_VALUE;
		private int upperBound = Integer.MAX_VALUE;

		public Builder(String primaryName, String valuePlaceholder, boolean obligatory) {
			super(primaryName, valuePlaceholder, obligatory);
		}

		public Builder(String primaryName, String valuePlaceholder) {
			super(primaryName, valuePlaceholder);
		}

		@Override
		public IntegerOption buildOption() {
			return new IntegerOption(this);
		}

		public int getLowerBound() {
			return lowerBound;
		}

		public Builder setLowerBound(int lowerBound) {
			this.lowerBound = lowerBound;
			return this;
		}

		public int getUpperBound() {
			return upperBound;
		}

		public Builder setUpperBound(int upperBound) {
			this.upperBound = upperBound;
			return this;
		}

	}

}
